/*
 * @FileName: app_comm.c
 * @Author: GreyQiu qiushaogui@aikosolar.com
 * @Date: 2023-08-21 16:44:35
 * @LastEditors: GreyQiu qiushaogui@aikosolar.com
 * @LastEditTime: 2023-09-26 10:49:21
 * @Description: 
 * 
 * Copyright (c) 2023, All Rights Reserved. 
 */

#include "app_analog.h"
#include "bms_can.h"
#include "app_fsm.h"
#include "app_fault.h"
#include "app_calibration.h"
#include "dev_info.h"
#include "bsp.h"

bms_data_t batteryMsg;
bms_alarm_t batteryWarn;
bms_protect_t batteryPrt;

/**
 * 以下为各个命令的handler
 */
void bms_handle_0X351(uint16_t cmd, uint16_t * data, uint16_t len)
{
    batteryMsg.maxVol = (data[1] << 8) + data[0];
    batteryMsg.currChg = (data[3] << 8) + data[2];
    batteryMsg.currDisChg = (data[5] << 8) + data[4];
    batteryMsg.minVol = (data[7] << 8) + data[6];
}

void bms_handle_0X355(uint16_t cmd, uint16_t * data, uint16_t len)
{
    batteryMsg.SOC = (data[1] << 8) + data[0];
    batteryMsg.SOH = (data[3] << 8) + data[2];
    batteryMsg.cellMaxVol = (data[5] << 8) + data[4];
    batteryMsg.cellMinVol = (data[7] << 8) + data[6];
}

void bms_handle_0X356(uint16_t cmd, uint16_t * data, uint16_t len)
{
    batteryMsg.voltage = (data[1] << 8) + data[0];
    batteryMsg.current = (data[3] << 8) + data[2];
    batteryMsg.cellMaxTmp = (data[5] << 8) + data[4];
    batteryMsg.cellMinTmp = (data[7] << 8) + data[6];
}

void bms_handle_0X359(uint16_t cmd, uint16_t * data, uint16_t len)
{
    batteryMsg.cap = (data[6] << 8) + data[5];

    batteryPrt.word = (data[1] << 8) + data[0];
    batteryWarn.word = (data[3] << 8) + data[2];
}
bsm_cmd_t cmd_table[BSM_CMD_NUM] = {
    {.cmd = 0x351, .handler = bms_handle_0X351},
    {.cmd = 0x355, .handler = bms_handle_0X355},
    {.cmd = 0x356, .handler = bms_handle_0X356},
    {.cmd = 0x359, .handler = bms_handle_0X359},
};

void bms_handle(uint16_t cmd, uint16_t * data, uint32_t len)
{
    bsm_cmd_t * obj = NULL;
    // 从表中顺序查找命令，如果命令表长度很大，建议使用二分查找
    uint16_t i;
    for (i = 0; i < BSM_CMD_NUM; i++) {
        if (cmd_table[i].cmd == cmd) {
            obj = &cmd_table[i];
            break;
        }
    }

    if (obj->handler != NULL) {
        obj->handler(cmd, data, len);
    }
}

